grammar SqfwPdfExcel;

parse
    : exper EOF;

exper
    : statement
    ;

statement
    :   ID  #statementIDTag
    |   StringLiteral #statementStrTag
    |   block   #blockTag
    |   '(' statement ')' '+' '(' statement ')' #addStatementTag
    |   '如果' parExpression statement ('否则' statement)? # ifCTag
    |   'if' parExpression statement ('@else@' statement)?    #ifTag
    |   statementExpression #singleStatementTag
    |   assignExpression','assignExpression #multiAssign
    ;

block
    :   '则{' statement* '}' #blockContentCTag
    |   '{' statement* '}'  #blockContentTag
    ;

parExpression
    :   '(' expression ')'  #paramContentTag
    ;

statementExpression
    :   expression
    ;

expression
    :   ID  #idExpressionTag
    |   StringLiteral #stringExpressTag
    |   '(' expression '+' expression ')' # middleAddExpressionTag
    |   expression isBlankExpression    #isBlankExpressionTag
    |   expression isNotBlankExpression #isBlankExpressionTag
    |   expression ('*'|'/'|'%') expression #mulDivExpressionTag
    |   expression ('+'|'-') expression #addSubExpressionTag
    |   expression ('<=' | '>=' | '>' | '<') expression #compareExpressionTag
    |   expression ('==' | '!=') expression #isEqualExpressTag
    |   expression ('包含'|'含有'|'不包含'|'不含有') expression #containExpressCTag
    |   expression ('@contain@' | '@not_contain@') expression #containExpressTag
    |   expression ('包含'|'含有'|'不包含'|'不含有') setContentExpression '任意一项'?  #containAnyOneCExpressionTag
    |   expression ('@contain@' | '@not_contain@') setContentExpression '@anyOne@'?  #containAnyOneExpressionTag
    |   '计算' ID ',' ID '时差' dateOffsetUnit? #calcTimeBetweenCTag
    |   '@calculate@' ID  ',' ID '@date_between@' dateOffsetUnit? #calcTimeBetweenTag
    |   '替换' expression '中' StringLiteral '为' StringLiteral  #replaceCTag
    |   '@replace@' expression 'from' StringLiteral 'to' StringLiteral  #replaceTag
    |   expression '&&' expression  #andExpressionTag
    |   expression '并且' expression  #andCExpressionTag
    |   expression '或者' expression  #orExpressionCTag
    |   expression '||' expression  #orExpressionTag
    |   expression '?' expression ':' expression    #threeExpressionTag
    |   assignExpression  #assignExpressionTag
    |   baseAssignExpression #baseAssignExpressionTag
    ;

setContentExpression
    :   '[' StringLiteral (','StringLiteral)* ']'
    ;

isBlankExpression
    : '没有值'
    |  'noValue'
    ;

isNotBlankExpression
    :  '不为空'
    |  '有值'
    |  'notBlank'
    ;

baseAssignExpression
//    : <assoc=right> ('=' | '赋值') expression
    : ('=' | '赋值') expression
    ;

assignExpression
    :   <assoc=right> ID ('=' | '赋值') expression
    ;

dateOffsetUnit
    :   '(' StringLiteral ')'
    ;

ID : [a-zA-Z0-9]+;
DATESTR:[YyMmDdHhSs-]+;
WHITESPACE: [ \r\n\t]+ -> skip;

// 定义什么是字符串
StringLiteral
    :   '"' StringCharacters? '"'
    ;

fragment
StringCharacters
    :   StringCharacter+
    ;

fragment
StringCharacter
    :   ~["\\]
    |   EscapeSequence
    ;

fragment
EscapeSequence
    :   '\\' [btnfr"'\\]
    |   OctalEscape
    |   UnicodeEscape
    ;

fragment
OctalEscape
    :   '\\' OctalDigit
    |   '\\' OctalDigit OctalDigit
    |   '\\' ZeroToThree OctalDigit OctalDigit
    ;

fragment
UnicodeEscape
    :   '\\' 'u' HexDigit HexDigit HexDigit HexDigit
    ;

fragment
OctalDigit
    :   [0-7]
    ;

fragment
ZeroToThree
    :   [0-3]
    ;

fragment
HexDigit
    :   [0-9a-fA-F]
    ;

// 定义boolean类型
BooleanLiteral
    :   'true'
    |   'false'
    ;
